﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ServiceStack.Redis;

namespace EventViewToExceptionless
{
    /// <summary>
    /// redis客户端
    /// ServiceStack.Redis.Complete:redis免费版客户端，csredis的framework版本可能有异常
    /// </summary>
    public class ServiceStackRedis : IServiceStackRedis
    {
        private static string _host;

        private static int _port;

        private static string _password;

        private static string _connection;

        /// <summary>
        /// 初始化redis
        /// 在Web.config中的appSettings节点下配置redis主机，如下: <add key="RedisServer" value="locahost:6375" />
        /// </summary>
        static ServiceStackRedis()
        {
            try
            {
                _connection = ConfigurationManager.AppSettings["RedisServer"].ToString();
                if (!string.IsNullOrWhiteSpace(_connection))
                {
                    var connArr = _connection.Split(',');
                    var serverStr = _connection;
                    if (connArr.Length == 2)
                    {
                        serverStr = connArr[0];
                        var pwd = connArr[1].Split('=');
                        if (pwd.Length == 2)
                        {
                            _password = pwd[1].Trim();
                        }
                    }
                    var server = serverStr.Split(':');
                    if (server.Length != 2) return;

                    _host = server[0];
                    _port = int.Parse(server[1]);
                }
            }
            catch (Exception)
            {
                _host = "localhost";
                _port = 6375;
            }
        }

        private RedisClient RedisClient
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(_password))
                {
                    return new RedisClient(_host, _port, _password);
                }

                return new RedisClient(_host, _port);
            }
        }

        public T Get<T>(string key)
        {
            try
            {
                using (RedisClient client = this.RedisClient)
                {
                    var bytes = client.Get(key);
                    if (bytes == null) return default(T);
                    return ConvertObj<T>(bytes);
                }
            }
            catch (Exception)
            {
                return default(T);
            }
        }

        public bool KeyDelete(params string[] keys)
        {
            try
            {
                using (RedisClient client = this.RedisClient)
                {
                    return client.Del(keys) > 0 ? true : false;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool KeyExists(string key)
        {
            try
            {
                using (RedisClient client = this.RedisClient)
                {
                    return client.Exists(key) > 0 ? true : false;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        public void Set<T>(string key, T obj, int expirationSeconds = 60)
        {
            try
            {
                using (RedisClient client = this.RedisClient)
                {
                    var bytes = Serialize(obj);
                    client.Set(key, bytes, TimeSpan.FromSeconds(expirationSeconds));
                }
            }
            catch (Exception)
            {
                return;
            }
        }

        /// <summary>
        /// 反序列化为实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        private static T ConvertObj<T>(byte[] value)
        {
            if (value == null) return default(T);
            return Exceptionless.Json.JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(value));
        }

        private static byte[] Serialize<T>(T item)
        {
            var jsonString = Exceptionless.Json.JsonConvert.SerializeObject(item);
            return Encoding.UTF8.GetBytes(jsonString);
        }
    }
}
